package com.clp.protocol.iec104.server.pipeline.state.control;

import com.clp.protocol.iec104.apdu.*;
import com.clp.protocol.iec104.server.pipeline.PipelineManager;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Nullable;

/**
 * 启动传输状态处理器，如果没有启动传输，那么就拒绝任何报文
 */
@Slf4j
public class DtControlStateHandler extends AbstractControlStateHandler {

    /**
     * 是否已经进行启动传输
     */
    @Getter
    private volatile boolean isStartedDt;
    /**
     * 上次启动传输时间
     */
    private volatile long lastStartDtTime;
    /**
     * 上次停止传输时间
     */
    private volatile long lastStopDtTime;

    public DtControlStateHandler(PipelineManager manager) {
        super(manager);
    }

    @Override
    protected void resetState() {
        isStartedDt = false;
        lastStartDtTime = System.currentTimeMillis();
        lastStopDtTime = System.currentTimeMillis();
    }

    @Override
    protected void afterResetState() {

    }

    /**
     * 接收到U帧，应用启动传输过程
     * @param uApdu
     * @return
     */
    @Override
    protected UApdu updateStateByRecv(UApdu uApdu) {
        switch (uApdu.getUApci().getCtrlArea().getUCtrlType()) {
            case U_START_DT_V:
                uApduSender().chSendStartDtC(); // 发送启动传输确认
                break;
            case U_STOP_DT_V:
                uApduSender().chSendStopDtC(); // 发送停止传输确认
                break;
        }
        return uApdu;
    }

    @Override
    protected SApdu updateStateByRecv(SApdu sApdu) {
        return sApdu; // 放行
    }

    @Override
    protected IApdu updateStateByRecv(IApdu iApdu) {
        return iApdu;
    }

    @Override
    protected UApdu updateStateBySend(UApdu uApdu) {
        switch (uApdu.getUApci().getCtrlArea().getUCtrlType()) {
            case U_START_DT_C:
                isStartedDt = true;
                lastStartDtTime = System.currentTimeMillis();
                break;
            case U_STOP_DT_C:
                isStartedDt = false;
                lastStopDtTime = System.currentTimeMillis();
                break;
        }
        return uApdu;
    }

    @Override
    protected SApdu updateStateBySend(SApdu sApdu) {
        return sApdu; // 直接放行S帧
    }

    @Override
    protected IApdu updateStateBySend(IApdu iApdu) {
        return iApdu;
    }

    @Override
    @Nullable
    protected ScheduledTask getScheduledTask() {
        return null;
    }
}
